package com.example.demo.controller;


import com.example.demo.model.Accessories;
import com.example.demo.model.ApplicationInformation;
import com.example.demo.model.ApplicationInformationDTO;
import com.example.demo.model.EnterpriseInfo;
import com.example.demo.repository.ApplicationInformationRepository;
import com.example.demo.repository.EnterpriseInfoRepository;
import com.example.demo.util.*;
import net.sf.json.JSONObject;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.interfaces.RSAPrivateKey;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import static com.example.demo.controller.RestUploadController.dateToStamp;
import static com.example.demo.util.AESUtil.AES_CBC_Decrypt;


/**
 * Created by huang on 2018/1/9.
 */
@RequestMapping("/api/v1")
@RestController
public class ApplicationController extends BaseController{
    @Autowired
    ApplicationInformationRepository applicationInformationRepository;
    @Autowired
    EnterpriseInfoRepository enterpriseInfoRepository;

    private int k = 1; // 定义递归次数变量
    @Value("${web.upload-temp}")
    String UPLOADED_FOLDER = "";
    @PostMapping("/import")
    public ResponseEntity<?> importData(@RequestParam("file") MultipartFile uploadFile, HttpServletRequest request) throws Exception {
        //创建word存放地点
        long time = new Date().getTime();
        String timeStamp = String.valueOf(time);
        File fileUpload = new File(UPLOADED_FOLDER);
        if(!fileUpload.exists()){
            fileUpload.mkdir();
        }
        fileUpload = new File(UPLOADED_FOLDER+"archives/");
        if(!fileUpload.exists()){
            fileUpload.mkdir();
        }
       /* fileUpload = new File(UPLOADED_FOLDER+"files/");
        if(!fileUpload.exists()){
            fileUpload.mkdir();
        }
        fileUpload = new File(UPLOADED_FOLDER+"result/");
        if(!fileUpload.exists()){
            fileUpload.mkdir();
        }*/
            //创建临时文件夹 temp
        File file = new File(UPLOADED_FOLDER+"temp");
        file.mkdir();
        String unName = uploadFile.getOriginalFilename().substring(0, uploadFile.getOriginalFilename().indexOf("_"));
        String[] address = new String[10];
        address = saveUploadedFiles1(Arrays.asList(uploadFile));

        ZipFile zipFile = new ZipFile(UPLOADED_FOLDER+"temp/"+uploadFile.getOriginalFilename());
        Enumeration<ZipEntry> enu = (Enumeration<ZipEntry>) zipFile.entries();
        while (enu.hasMoreElements()){
            ZipEntry zipElement = (ZipEntry) enu.nextElement();
            InputStream read = zipFile.getInputStream(zipElement);
            String fileName = zipElement.getName();
            if (fileName != null && fileName.indexOf(".") != -1) {// 是否为文件
                AppUtil.unZipFile(zipElement, read, UPLOADED_FOLDER+"temp/");
            }
        }

        //获取私钥
        RSAPrivateKey privateKey = RSAUtil.getPrivateKey(getClass().getClassLoader().getResourceAsStream("private.pem"));//filename.getClass().getResourceAsStream(filename)
        //读取已经公钥加密的AES密钥文件--记录AES加密时候产生的随机数
        String encodedSecrete = IOUtil.getContent(UPLOADED_FOLDER+"temp/key.secrete");
        //解密该随机数
        String secrete = RSAUtil.decrypt(encodedSecrete, privateKey);
        //读取加密过的申请文件
        File unZip = new File(UPLOADED_FOLDER+"temp/files.kgj");
        byte[] encodedFileBytes = AppUtil.getBytes1(UPLOADED_FOLDER+"temp/files.kgj");
        //文件转码和解密,输入上面解析出的随机数
        byte[] decoded = AES_CBC_Decrypt((encodedFileBytes), AESUtil.genSkc(secrete), false);
        FileOutputStream fileOutputStream = new FileOutputStream(new File(UPLOADED_FOLDER+unName+".zip"));
        fileOutputStream.write(decoded);
        fileOutputStream.flush();

        //创建临时文件夹 temp
        File file1 = new File(UPLOADED_FOLDER+"temp/untemp");
        if(!file1.exists()){//判断文件夹是否创建，没有创建则创建新文件夹
            file1.mkdirs();
        }
        String UNZIP_FILE_DIR = UPLOADED_FOLDER+"archives/"+timeStamp+"_"+uploadFile.getOriginalFilename().substring(0, uploadFile.getOriginalFilename().indexOf("."));
        String UNZIP_FILE_DIR_SERVER = "/upload/archives/"+timeStamp+"_"+uploadFile.getOriginalFilename().substring(0, uploadFile.getOriginalFilename().indexOf("."));
        ZipFile decryptedZipFIle = new ZipFile(UPLOADED_FOLDER+unName+".zip");

        //解压缩到Archives文件夹
        AppUtil.unzipIt(UPLOADED_FOLDER+unName+".zip", UNZIP_FILE_DIR);

        File unzippedFile = new File(UNZIP_FILE_DIR);
        ApplicationInformation applicationInformation = new ApplicationInformation();
        Accessories accessories = new Accessories();
        for (String subFileName : unzippedFile.list()) {
            if(subFileName.indexOf(".json")>-1){
                File jsonFile=new File(UNZIP_FILE_DIR+"/"+subFileName );
                String jsonStr= FileUtils.readFileToString(jsonFile,"UTF-8").replaceAll(" +","");
                JSONObject jsonObject = JSONObject.fromObject(jsonStr);
                ApplicationInformationDTO applicationInformationImportDTO = (ApplicationInformationDTO) JSONObject.toBean(jsonObject, ApplicationInformationDTO.class);
                BeanUtils.copyProperties(applicationInformationImportDTO, applicationInformation, new String[]{"id", "mtcsol", "secretCommittee"});
                applicationInformation.setProvince(AddressUtil.getProvinceByFullCode(applicationInformation.getCreditCode()));
                applicationInformation.setSecretCommittee(AppUtil.matrixToRow(applicationInformationImportDTO.getSecretCommittee()));
                applicationInformation.setMtcsol(AppUtil.matrixToRow(applicationInformationImportDTO.getMtcsol()));
                applicationInformation.setSource("导入");
            }
            else if(subFileName.indexOf(".doc")>-1)
                applicationInformation.setWord(UNZIP_FILE_DIR+"/"+subFileName);
        }
        List<String> credentialList = new ArrayList<>();
        List<String> regulationList = new ArrayList<>();
        List<String> licenseList = new ArrayList<>();
        String[] dirs = {"/附件/保密资格认定等级建议表/", "/附件/财务审计报表/", "/附件/工商营业执照/", "/附件/公司章程/", "/附件/生产场所产权证书或租赁合同/", "/附件/其他/"};
        accessories.setLevel(genAccessories(licenseList, dirs[0], UNZIP_FILE_DIR, UNZIP_FILE_DIR_SERVER));
        accessories.setFinance(genAccessories(credentialList, dirs[1], UNZIP_FILE_DIR, UNZIP_FILE_DIR_SERVER));
        accessories.setLicense(genAccessories(regulationList, dirs[2], UNZIP_FILE_DIR, UNZIP_FILE_DIR_SERVER));
        accessories.setRegulations(genAccessories(regulationList, dirs[3], UNZIP_FILE_DIR, UNZIP_FILE_DIR_SERVER));
        accessories.setContract(genAccessories(regulationList, dirs[4], UNZIP_FILE_DIR, UNZIP_FILE_DIR_SERVER));
        accessories.setOthers(genAccessories(regulationList, dirs[5], UNZIP_FILE_DIR, UNZIP_FILE_DIR_SERVER));


        applicationInformation.setAccessories(accessories);
        //把处理好的信息存到单位详细信息中一份
        List<EnterpriseInfo> enterpriseInfo = enterpriseInfoRepository.findByCreditCode(applicationInformation.getCreditCode());
        EnterpriseInfo enterpriseInfo1;
        if(enterpriseInfo.size() == 0 ){
            enterpriseInfo1 = new EnterpriseInfo();
        }else{
            enterpriseInfo1 = enterpriseInfo.get(0);
        }
        BeanUtils.copyProperties(applicationInformation ,enterpriseInfo1, new String[]{"id"});
        enterpriseInfoRepository.save(enterpriseInfo1);
        applicationInformation.setCreateTime(new Date());
        applicationInformationRepository.save(applicationInformation);
        //删除临时文件夹 temp
        AppUtil.deleteDir(file);
        State state = new State();
        state.setState("success");
        state.setUrl(address[0]);
        return new ResponseEntity(state, new HttpHeaders(), HttpStatus.OK);
    }

    private List<String> genAccessories(List<String> list, String dir, String UNZIP_FILE_DIR, String UNZIP_FILE_DIR_SERVER) {
        String basePath = UNZIP_FILE_DIR+dir;
        String uploadBasePath = UNZIP_FILE_DIR_SERVER+dir;
        File accessoriesDir;
        accessoriesDir = new File(basePath);
        if(accessoriesDir.exists()){
            for(String subFileName: accessoriesDir.list()){
                list.add(uploadBasePath+subFileName);
            }
        }
        return list;
    }


    private String[] saveUploadedFiles1(List<MultipartFile> files) throws IOException, ParseException {
        String[] fileAddress = new String[files.size()];
        int index = 0;
        for (MultipartFile file : files) {

            if (file.isEmpty()) {
                continue; //next pls
            }
            byte[] bytes = file.getBytes();
            Date currentTime = new Date();
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String date = format.format(currentTime);
            String fileName=file.getOriginalFilename();
            String prefix=fileName.substring(fileName.lastIndexOf(".")+1);
            Path path = Paths.get(UPLOADED_FOLDER+"temp/" + fileName);
            Files.write(path, bytes);
            fileAddress[index] = "/upload/" + dateToStamp(date)+prefix;
            index++;
        }
        return fileAddress;
    }


    //TODO 申请审批  应该存两个word 的地址 Uplad实体是图片 存在applicationInformation 即可
   /* @PostMapping("/applications/handleResult")
    public ResponseEntity applicationResult(HttpServletRequest request, @RequestBody AppDTO appDTO ){
        ApplicationInformation applicationInformation = applicationInformationRepository.findById(appDTO.getId());
        applicationInformation.setResult(appDTO.getResult() == null? "":appDTO.getResult());
        applicationInformation.setScore(appDTO.getScore() == null? "":appDTO.getScore());
        if (appDTO.getResult() != null){
            if ("受理".equals(appDTO.getResult())){
                applicationInformation.setStatus("处理中");
            }else if ("".equals(appDTO.getResult())){
                applicationInformation.setStatus("未处理");
            }else{
                applicationInformation.setStatus("已完成");
            }
        }
        applicationInformationRepository.save(applicationInformation);
        State state = new State();
        state.setState("success");
        return new ResponseEntity(state, new HttpHeaders(), HttpStatus.OK);
        return null;
    }
   @PostMapping("/import/suggestionFile/{id}")
    public Upload importSuggestionFile(@PathVariable int id, @RequestParam("file") MultipartFile uploadfile, HttpServletRequest request) throws IOException, ParseException {
        ApplicationInformation applicationInformation = applicationInformationRepository.findById(id);
        String[] address = saveUploadedFiles(Arrays.asList(uploadfile), UPLOADED_FOLDER+"result/");
        if(applicationInformation.getUpload() == null)
            applicationInformation.setUpload(new Upload());
        applicationInformation.getUpload().setSuggestionFile(address[0]);
        applicationInformationRepository.save(applicationInformation);
        //TODO 上传返回地址
        System.out.println("上传返回地址直接可以访问"+address[0]);
        return applicationInformation.getUpload();

    }


    @PostMapping("/import/recordFile/{id}")
    public Upload importRecordFile(@PathVariable int id, @RequestParam("file") MultipartFile uploadfile, HttpServletRequest request) throws IOException, ParseException {
        ApplicationInformation applicationInformation = applicationInformationRepository.findById(id);
        String[] address = saveUploadedFiles(Arrays.asList(uploadfile), UPLOADED_FOLDER+"result/");
        if(applicationInformation.getUpload() == null)
            applicationInformation.setUpload(new Upload());
        applicationInformation.getUpload().setRecordFile(address[0]);
        applicationInformationRepository.save(applicationInformation);
        //TODO 上传返回地址
        System.out.println("上传返回地址直接可以访问"+address[0]);
        return  applicationInformation.getUpload();
    }*/

}
